home *** CD-ROM | disk | FTP | other *** search
- ###makefile.
- FILES=bj.c error.c dekmgr.c \
- getbet.c hndmgr.c nfrom.c outcom.c query.c takes.c
-
- OBJECTS=bj.o error.o dekmgr.o \
- getbet.o hndmgr.o nfrom.o outcom.o query.o takes.o
-
- DEFS=local.h bj.h dekmgr.h hndmgr.h ttymgr.h
-
- LINT=lint -phbxac
-
- cleanup:
- -rm *.o
- -du
-
- install:
- size bj /a1/phi/bin/bj
- cp bj /a1/phi/bin/bj; rm bj
-
- print: Makefile $(DEFS) $(FILES)
- pr $?
- date >print
-
- bj: $(DEFS) $(OBJECTS)
- cc -o bj $(OBJECTS)
-
- bj.lint: $(DEFS) $(FILES)
- $(LINT) >bj.lint $(FILES)
-
- outcom.x: $(DEFS) outcom.c error.o
- cc -o outcom.x -DTRYMAIN outcom.c error.o
-
- all:
- make bj
- make bj.lint
- make install
- ###bj.c
- /* bj - blackjack
- * Permission is hereby granted to reproduce and use bj
- */
- #include "local.h"
- #include "bj.h"
- #include "dekmgr.h"
- #include "hndmgr.h"
- #include "ttymgr.h"
- main()
- {
- CASH action; /* how much money has crossed the table */
- CASH bet; /* amount of player's current bet per hand */
- CASH result; /* net result of this hand, plus or minus */
- CASH standing; /* how much has player won or lost */
- bool canhit; /* can player's hand take hit? */
- bool isdbl; /* did player take DBLDN? */
- bool isinsur; /* did player take insurance? */
- short hand; /* current hand number */
- short reply; /* player's reply to DBLDN, SPLIT */
- short tophand; /* how many hands is player playing, 1 or 2 */
-
- printf("Copyright (c) Plum Hall Inc, 1983\n");
- /* permission to copy and modify is granted, provided that
- * this printout and comment remain intact
- */
- printf("\nWelcome to the Blackjack table\n");
- action = standing = 0;
- opndek();
- while ((bet = getbet()) != 0)
- {
- tophand = 1;
- isinsur = isdbl = NO;
- if (deklow())
- shuffl();
- deal();
- if (val(DEALER, 0) == 11)
- isinsur = takes("i");
- reply = query();
- if (reply == SPLIT)
- tophand = split();
- else if (reply == DBLDN)
- {
- hit(1);
- printf("\n");
- isdbl = YES;
- bet *= 2;
- }
- for (hand = 1; hand <= tophand; ++hand)
- {
- if (tophand == 2)
- printf("Hand %d:\n", hand);
- canhit = !isdbl;
- canhit &= !isbj(1);
- canhit &= (reply != SPLIT || val(1, 0) != 11);
- while (canhit && takes("h"))
- {
- canhit = hit(hand);
- printf("\n");
- }
- if (21 < score(hand))
- printf("Bust\n");
- }
- printf("Dealer has ");
- show(DEALER, 0);
- printf(" + ");
- show(DEALER, 1);
- if (!allbst())
- while (score(DEALER) < 17)
- hit(DEALER);
- printf(" = %d\n", score(DEALER));
- result = outcom(bet, tophand, isinsur, isdbl);
- action += ABS(result);
- standing += result;
- printf("action = ");
- printf(CASHOUT, action);
- printf(" standing = ");
- printf(CASHOUT, standing);
- printf("\n");
- }
- printf("\nThanks for the game.\n");
- exit(SUCCEED);
- }
- ###bj.h
- /* bj.h - include-file for blackjack
- */
-
- /* defined types
- */
- #define CASH long /* dollars */
-
- /* defined constants
- */
- #define DEALER 0 /* which hand is dealer; not modifiable */
- #define NONE 0 /* no reply */
- #define DBLDN 1 /* reply: double down */
- #define SPLIT 2 /* reply: split pair */
- #define INSUR 3 /* takes: insurance */
- #define HIT 4 /* takes: hit */
- #define CASHIN "%ld" /* input format for CASH data */
- #define CASHOUT "%ld" /* output format for CASH data */
- ###dekmgr.c
- /* dekmgr - deck manager
- */
- #include "local.h"
- #include "bj.h"
- #include "dekmgr.h"
- #define NCARDS 4 * 52
- static short deck[NCARDS] = 0; /* the deck */
- static short nc = 0; /* subscript of next card */
- static short shufpt = 0; /* subscript of shuffle point */
- /* deklow - is deck at or past shuffle point?
- */
- bool deklow()
- {
- return (shufpt <= nc);
- }
- /* opndek - initialize the deck
- */
- void opndek()
- {
- short i;
- short low;
- short varnum();
-
- for (low = 0; low < NCARDS; low += 52)
- for (i = 0; i < 52; ++i)
- deck[i + low] = i;
- srand(varnum());
- shuffl();
- }
- /* shuffl - shuffle the deck
- */
- void shuffl()
- {
- short t; /* temporary for swap */
- short i; /* index for loop over cards */
- short j; /* index for swap */
- short nfrom(); /* fn to produce random number */
-
- for (i = 0; i < NCARDS - 1; ++i)
- {
- j = nfrom(i, NCARDS - 1);
- t = deck[j], deck[j] = deck[i], deck[i] = t;
- }
- shufpt = nfrom(NCARDS - 52, NCARDS - 36);
- nc = 0;
- printf("Shuffle\n");
- }
-
-
-
- /* tkcard - take a card
- */
- short tkcard()
- {
- if (NCARDS <= nc)
- shuffl();
- return (deck[nc++]);
- }
- /* varnum - return a varying startoff number
- */
- short varnum()
- {
- long time(); /* SYSTEM DEPENDENT - NEEDS CLOCK */
-
- return ((short)time(0));
- }
- ###dekmgr.h
- /* dekmgr.h - interface for deck manager
- */
- bool deklow();
- void opndek();
- void shuffl();
- short tkcard();
- ###error.c
- /* error - print fatal error message
- */
- #include "local.h"
- void error(s1, s2)
- char s1[], s2[];
- {
- write(STDERR, s1, strlen(s1));
- write(STDERR, " ", 1);
- write(STDERR, s2, strlen(s2));
- write(STDERR, "\n", 1);
- exit(FAIL);
- }
- ###getbet.c
- /* getbet - get the player's bet
- */
- #include "local.h"
- #include "bj.h"
- #define MINBET 2
- #define MAXBET 1000
- CASH getbet()
- {
- char line[BUFSIZ]; /* input line */
- short retn; /* return from getln and sscanf */
- CASH bet; /* player's bet */
-
- printf("\n\nYour bet (amount): ");
- FOREVER
- {
- retn = getln(line, BUFSIZ);
- if (retn == EOF)
- return (0);
- retn = sscanf(line, CASHIN, &bet);
- if (retn != 1 || bet < MINBET || MAXBET < bet)
- printf("Number from %d to %d please: ",
- MINBET, MAXBET);
- else
- return (bet);
- }
- }
- ###hndmgr.c
- /* hndmgr - hand manager
- */
- #include "local.h"
- #include "bj.h"
- #include "hndmgr.h"
- #include "dekmgr.h"
- static char spots[13][3] =
- {"A", "2", "3", "4", "5", "6", "7", "8", "9",
- "10", "J", "Q", "K"};
- static char suits[4][2] = {"S", "H", "D", "C"};
- static short hands[3][12] = 0; /* three hands */
- static short ncards[3] = 0; /* how many cards in each hand */
- static short tophand = 0; /* how many player hands active */
- /* allbst - are all player's hands busted?
- */
- bool allbst()
- {
- if (score(1) <= 21 || (tophand == 2 && score(2) <= 21))
- return (NO);
- else
- return (YES);
- }
- /* deal - initialize the hands
- */
- void deal()
- {
- hands[1][0] = tkcard();
- hands[DEALER][0] = tkcard();
- hands[1][1] = tkcard();
- hands[DEALER][1] =tkcard();
- ncards[DEALER] = ncards[1] = 2;
- tophand = 1;
- printf("The dealer shows ");
- show(DEALER, 0);
- printf("\nYou have ");
- show(1, 0);
- printf(" + ");
- show(1, 1);
- printf("\n");
- }
-
-
-
-
-
-
-
-
-
-
- /* hit - add a card to a hand
- */
- bool hit(h)
- short h; /* which hand */
- {
- hands[h][ncards[h]] = tkcard();
- printf(" + ");
- show(h, ncards[h]);
- ++ncards[h];
- if (21 < score(h) || h == DEALER && 17 <= score(h))
- return (NO);
- else
- return (YES);
- }
- /* isbj - is hand a "natural" 2-card blackjack?
- */
- bool isbj(h)
- short h; /* which hand */
- {
- if (h == DEALER)
- return (ncards[DEALER] == 2 && score(DEALER) == 21);
- else if (h == 1)
- return (tophand == 1 && ncards[1] == 2 && score(1) == 21);
- else
- return (NO);
- }
- /* score - tell blackjack value of hand
- */
- short score(h)
- short h; /* which hand */
- {
- short aces = 0; /* number of aces in hand */
- short i; /* card counter */
- short sum = 0; /* accumulated value of hand */
-
- for (i = 0; i < ncards[h]; ++i)
- {
- sum += val(h, i);
- if (val(h, i) == 11)
- ++aces;
- }
- for (i = aces; 0 < i; --i)
- if (21 < sum)
- sum -= 10;
- return (sum);
- }
-
-
-
-
- /* show - print a card
- */
- void show(h, i)
- short h; /* which hand */
- short i; /* which card */
- {
- printf("%s", spots[hands[h][i] % 13]);
- printf("%s", suits[hands[h][i] / 13]);
- }
- /* split - split the players pair if allowed
- */
- short split()
- {
- if (val(1, 0) != val(1, 1))
- return (1);
- hands[2][0] = hands[1][1];
- hands[1][1] = tkcard();
- hands[2][1] = tkcard();
- ncards[2] = 2;
- printf("Hand 1: "); show(1, 0); printf(" + "); show(1, 1);
- printf("\n");
- printf("Hand 2: "); show(2, 0); printf(" + "); show(2, 1);
- printf("\n");
- tophand = 2;
- return (2);
- }
- /* val - tell value of card n of hand h
- */
- short val(h, i)
- short h; /* which hand */
- short i; /* which card */
- {
- short n; /* spots value of card */
-
- n = (hands[h][i] % 13) + 1;
- if (n > 9)
- return (10);
- else if (n == 1)
- return (11);
- else
- return (n);
- }
- ###hndmgr.h
- /* hndmgr.h - interface for hand manager
- */
- bool allbst();
- void deal();
- bool hit();
- bool isbj();
- CASH outcom();
- short score();
- void show();
- short split();
- short val();
- ###local.h
- /* local.h - definitions for use with
- * Learning to Program in C
- */
- #ifndef FAIL
- #include <stdio.h>
- #define FAIL 1
- #define FOREVER for (;;)
- #define NO 0
- #define STDERR 2
- #define STDIN 0
- #define STDOUT 1
- #define SUCCEED 0
- #define YES 1
- #define bits ushort
- #define bool int
- #define metachar short
- #define tbool char
- #define ushort unsigned /* use unsigned short, if you can */
- #define void int
- #define getln(s, n) ((fgets(s, n, stdin)==NULL) ? EOF : strlen(s))
- #define ABS(x) (((x) < 0) ? -(x) : (x))
- #define MAX(x, y) (((x) < (y)) ? (y) : (x))
- #define MIN(x, y) (((x) < (y)) ? (x) : (y))
- #endif
- ###nfrom.c
- /* nfrom - return a number between low and high, inclusive
- */
- #include "local.h"
- short nfrom(low, high)
- register short low, high;
- {
- short rand();
- register short nb = high - low + 1;
-
- return (rand() % nb + low);
- }
- ###outcom.c
- /* outcom - print outcome of hand(s)
- */
- #include "local.h"
- #include "bj.h"
- #include "hndmgr.h"
- static CASH value = 0;
- /* outcom - print outcome of hand and compute result
- */
- CASH outcom(bet, tophand, isinsur, isdbl)
- CASH bet; /* amount of player's bet */
- short tophand; /* how many player hands */
- bool isinsur; /* player took insurance? */
- bool isdbl; /* is player DBLDN? */
- {
- short h; /* which hand */
-
- value = 0;
- if (isinsur && isbj(DEALER))
- prmsg(1, 1, "Insurance wins\n", bet / (isdbl ? 4 : 2));
- else if (isinsur)
- prmsg(1, 1, "Insurance loses\n", -bet / (isdbl ? 4 : 2));
- if (isbj(DEALER) && !isbj(1))
- prmsg(1, 1, "Dealer BJ beats all but BJ",
- -bet / (isdbl ? 2 : 1));
- else if (isbj(DEALER) && isbj(1))
- prmsg(1, 1, "Both BJ: push", (CASH)0);
- else if (isbj(1))
- prmsg(1, 1, "Your BJ wins 3 for 2", (3 * bet) / 2);
- else
- {
- for (h = 1; h <= tophand; ++h)
- {
- if (21 < score(h))
- value -= bet; /* "Bust" message printed already */
- else if (score(DEALER) == score(h))
- prmsg(h, tophand, "Push", (CASH)0);
- else if (score(DEALER) < score(h) || 21 < score(DEALER))
- prmsg(h, tophand, "Win", bet);
- else
- prmsg(h, tophand, "Lose", -bet);
- }
- }
- return (value);
- }
-
-
-
-
-
-
- /* prmsg - print appropriate message
- */
- static void prmsg(h, tophand, s, delta)
- short h; /* which hand */
- short tophand; /* how many hands */
- char s[]; /* message */
- CASH delta; /* change of value (+ | -) */
- {
- if (tophand == 2)
- printf("On hand %d, ", h);
- printf("%s\n", s);
- value += delta;
- }
- #ifdef TRYMAIN
- static short bj[2] = 0; /* isbj, for each hand */
- static short sc[3] = 0; /* hand scores, for testing */
- main()
- {
- char line[BUFSIZ]; /* line of test input */
- short len; /* returned value from input fn */
- short ibet; /* players bet, as short int */
- short ins; /* isinsur? */
- short toph; /* tophand */
- short dbl; /* isdbl? */
- CASH value; /* return from outcom */
-
- FOREVER
- {
- printf("%-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s %-8s\n",
- "bet", "toph", "ins", "dbl",
- "bj[0]", "bj[1]", "sc[0]", "sc[1]", "sc[2]");
- len = echoln(line, BUFSIZ);
- if (len == EOF)
- break;
- if (9 != sscanf(line, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
- &ibet, &toph, &ins, &dbl,
- &bj[0], &bj[1], &sc[0], &sc[1], &sc[2]))
- error("outcom input error", "");
- value = outcom((CASH)ibet, toph, ins, dbl);
- printf("outcom() = ");
- printf(CASHOUT, value);
- printf("\n");
- }
- }
-
-
-
-
-
-
- /* score - dummy version for testing
- */
- short score(h)
- short h; /* which hand */
- {
- return (sc[h]);
- }
- /* isbj - dummy version for testing
- */
- bool isbj(h)
- short h; /* which hand */
- {
- return (bj[h]);
- }
- /* echoln - get and echo an input line
- */
- short echoln(line, size)
- char line[];
- short size;
- {
- short len;
-
- if ((len = getln(line, size)) != EOF)
- printf("%s", line);
- return (len);
- }
- #endif
- ###ttymgr.c
- /* ttymgr - tty (terminal) manager
- */
- #include "local.h"
- #include "bj.h"
- #include "hndmgr.h"
- #include "ttymgr.h"
- #define NMSGS 4
- #define LENMSG 15
- static bool askedhit = NO;
- static bool wanthit = NO;
- static char qchar[NMSGS+1] = "dsih";
- static char qmsg[NMSGS][LENMSG+1] =
- {
- "Double down",
- "Split pair",
- "Insurance",
- "Hit",
- };
- static short nmsg[NMSGS] = 0;
- /* query - get players response for DBLDN, SPLIT, HIT
- */
- short query()
- {
- short ask();
- short ret; /* return from ask() */
-
- if (val(1, 0) == val(1, 1))
- ret = ask("dsh");
- else
- ret = ask("dh");
- askedhit = (ret != SPLIT);
- wanthit = (ret == HIT);
- if (wanthit)
- ret = NONE;
- return (ret);
- }
- /* takes - get a YES or NO reply to question
- */
- bool takes(s)
- char s[];
- {
- short ask();
-
- if (askedhit && strcmp(s, "h") == 0)
- {
- askedhit = NO;
- return (wanthit);
- }
- return (ask(s) != NONE);
- }
- /* ask - get a choice among alternatives
- */
- static short ask(s)
- char s[];
- {
- bool isbrief; /* is prompt brief? */
- char ans[BUFSIZ]; /* player's reply line */
- char c; /* player's one-char answer */
- short i; /* index over chars of s */
- short j; /* index over chars of qchar */
- short slen; /* length of s */
- static short msglim = 5; /* verbosity limit */
- unsigned strscn(); /* gives the index of c in s */
-
- isbrief = YES;
- slen = strlen(s);
- for (i = 0; i < slen; ++i)
- {
- j = strscn(qchar, s[i]);
- if (++nmsg[j] <= msglim)
- isbrief = NO;
- }
- if (isbrief)
- {
- for (i = 0; i < slen; ++i)
- printf("%c?", s[i]);
- printf("\n");
- }
- FOREVER
- {
- if (!isbrief)
- {
- printf("Type\n");
- for (i = 0; i < slen; ++i)
- printf("%c For %s\n",
- s[i], qmsg[strscn(qchar, s[i])]);
- printf("RETURN For None\n");
- }
- if (getln(ans, BUFSIZ) == EOF)
- error("Bye!", "");
- c = tolower(ans[0]);
- if (c == '\n')
- return (NONE);
- for (i = 0; i < slen; ++i)
- if (s[i] == c)
- return (1 + strscn(qchar, c));
- isbrief = NO;
- }
- }
-
- /* strscn - return the index of c in string s
- */
- unsigned strscn(s, c)
- char s[]; /* string to be scanned */
- char c; /* char to be matched */
- {
- register unsigned i;
-
- for (i = 0; s[i] != c && s[i] != '\0'; ++i)
- ;
- return (i);
- }
- ###ttymgr.h
- /* ttymgr.h - interface for tty manager
- */
- CASH getbet();
- bool takes();
- short query();
- ###mk_bj.bat
- lccm bj dekmgr getbet hndmgr nfrom outcom ttymgr ++ bj +dekmgr+getbet+hndmgr+nfrom+outcom+ttymgr
- ###bj.
- ###EOF
-